# @File   : model.py
# @Time   : 2020/09/12 21:40:52
# @Author : hyh
# @work   : 数据库基础类, 提供ORM封装操作
# here put the import lib
from .ext import db
from flask import g
import datetime


class BaseTable(db.Model):
    """
    系统基础类, 囊括了一些基础属性

    Attributes:
        is_delete:              int 0 未删除 1 已删除
        create_user_id:         int 创建用户id
        create_time:            datetime 创建时间
        last_modify_user_id:    int 最后编辑人id
        last_modify_time:       datetime 最后编辑时间
        delete_user_id:         int 删除人id
        delete_time:            datetime 删除时间
    """
    __abstract__ = True

    is_delete = db.Column(db.Integer, default=0)
    create_user_id = db.Column(db.Integer)
    create_time = db.Column(db.DateTime, default=datetime.datetime.now)
    last_modify_user_id = db.Column(db.Integer)
    last_modify_time = db.Column(db.DateTime, default=datetime.datetime.now)
    delete_user_id = db.Column(db.Integer)
    delete_time = db.Column(db.DateTime)

    @classmethod
    def __make_conditions(cls, params: dict = {}) -> list:
        """
        制作查询条件
        """
        conditions = []
        for col, value in params.items():
            attr = getattr(cls, col)
            if attr:
                conditions.append(attr == value)
        conditions.append(cls.is_delete == 0)
        return conditions

    def to_dict(self) -> dict:
        """
        转换为字典

        Returns:
            该类的字典对象, 用于返回json
        """
        result = {}
        for c in self.__table__.columns:
            value = getattr(self, c.name, None)
            if isinstance(value, bytearray):
                value = value.decode()
            result[c.name] = value
        return result

    def from_dict(self, json: dict = {}):
        """
        将前端的json请求数据转换为对象属性

        Args:
            json:请求数据
        """
        for column in self.__table__.columns:
            if column.name in json:
                setattr(self, column.name, json[column.name])

    def add(self, json: dict = None):
        """
        新增方法, 接受一个字典对象
        Args:
            json:   字典(前端json请求对象)
        """
        # 如果json不为空, 则进行赋值
        if json is not None:
            self.from_dict(json)
        self.is_delete = 0
        self.create_time = datetime.datetime.now()
        self.create_user_id = g.user_id
        db.session.add(self)
        # 会对id进行回写
        db.session.commit()

    def delete(self):
        """删除自身"""
        self.is_delete = 1
        self.delete_time = datetime.datetime.now()
        self.delete_user_id = g.user_id
        db.session.commit()

    def update(self, json: dict = None):
        """更新方法, 与新增类似, 接受一个字典参数"""
        if json is not None:
            self.from_dict(json)
        self.last_modify_time = datetime.datetime.now()
        self.last_modify_user_id = g.user_id
        db.session.commit()

    @classmethod
    def get(cls, value, col: str = 'id'):
        """
        根据某一列的某一项值获取第一个对象
        最初设计用于根据id查询

        Args:
            value:  列的值
            col:    列名, 默认id

        Returns:
            第一个符合条件的数据对象
        """
        return cls.query.filter(getattr(cls, col) == value and cls.is_delete == 0).first()

    @classmethod
    def list(cls, conditions: list = None, is_page: bool = True, page: int = 1, size: int = 50):
        """
        支持自定义条件和分页的列表查询(后续考虑拓展定制条件方法)

        Args:
            conditions: 查询条件, 为None则查询全部
            is_page:    是否分页
            page:       页码
            size:       每页条目数量
          
        Returns:
            查询结果, 注意分页和不分页的结果对象不同
        """
        query = cls.query if conditions is None else cls.query.fliter(
            *conditions)
        return query.paginate(page, size, error_out=False) if is_page else query.all()
